package tankgame03;

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Objects;
import java.util.Vector;

//为了让panel不停的重绘子弹，需要将Mypanel实现Runnable，当做一个线程使用
public class MyPanel extends JPanel implements KeyListener, Runnable {
	//定义我方坦克
	MyTank myTank;
	//定义敌人坦克，放入到Vector（线程安全）
	Vector<EnemyTank> enemyTanks = new Vector<>();
	//定义一个vector，用于存放炸弹
	//当子弹击中坦克时，就加入一个bomb对象
	static Vector<Bomb> bombs = new Vector<>();
	int enemyTankSize = 3;
	//定义一个vector，用于存放node恢复坦克的坐标和方向
	Vector<Node> nodes = new Vector<>();

	//定义三张炸弹图片，用于显示爆炸效果
	Image image1 = null;
	Image image2 = null;
	Image image3 = null;

	//坦克大战的绘图区域
	public MyPanel(String key) throws IOException {
		//判断记录文件是否存在，如果不存在提示只能开启新游戏
		String recordFile = Recorder.getRecordFile();
		File file = new File(recordFile);
		if (!file.exists() && Objects.equals(key, "2")) {
			System.out.println("只能开启新游戏");
			key = "1";
		}else {
			nodes = Recorder.getNodesAndEnemyTankRec();
		}
		Recorder.setEnemyTanks(enemyTanks);
		myTank = new MyTank(500, 100);//初始化己方坦克
		myTank.setSpeed(5);
		if (Objects.equals(key, "1")) {//新游戏
			//初始化敌方坦克
			for (int i = 0; i < enemyTankSize; i++) {
				EnemyTank enemyTank = new EnemyTank(100 * (i + 1), 0);
				enemyTank.setEnemyTanks(enemyTanks);
				enemyTank.setDirection(2);
				new Thread(enemyTank).start();
				//给该enemyTank加入一颗子弹
				Shot shot = new Shot(enemyTank.getX() + 20, enemyTank.getY() + 60, enemyTank.getDirection());
				enemyTank.shots.add(shot);
				//启动子弹
				new Thread(shot).start();
				enemyTanks.add(enemyTank);
			}
		} else if (Objects.equals(key, "2")) {//继续上局游戏
			for (int i = 0; i < nodes.size(); i++) {
				Node node = nodes.get(i);
				EnemyTank enemyTank = new EnemyTank(node.getX(), node.getY());
				enemyTank.setEnemyTanks(enemyTanks);
				enemyTank.setDirection(node.getDirect());
				new Thread(enemyTank).start();
				//给该enemyTank加入一颗子弹
				Shot shot = new Shot(enemyTank.getX() + 20, enemyTank.getY() + 60, enemyTank.getDirection());
				enemyTank.shots.add(shot);
				//启动子弹
				new Thread(shot).start();
				enemyTanks.add(enemyTank);
			}
		}
		else System.out.println("你的输入有误");
		//初始化图片对象
		image1 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/bomb1.png"));
		image2 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/bomb2.png"));
		image3 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/bomb3.png"));
	}

	public void hitMyTank() {
		//遍历所有敌人坦克
		for (int i = 0; i < enemyTanks.size(); i++) {
			//取出敌人坦克
			EnemyTank enemyTank = enemyTanks.get(i);
			//遍历所有子弹
			for (int j = 0; j < enemyTank.shots.size(); j++) {
				//判断是否击中了我发坦克
				Shot shot = enemyTank.shots.get(j);
				if (shot != null && shot.isLive && myTank.isLive) {
					hitTank(shot, myTank);
				}
			}
		}
	}

	public void hitEnemyTank(Vector<Shot> shots, Vector<EnemyTank> enemyTanks) {
		for (int i = 0; i < shots.size(); i++) {
			//判断是否击中了敌人坦克
			Shot shot = shots.get(i);
			if (shot != null && shot.isLive) {
				for (int j = 0; j < enemyTanks.size(); j++) {
					EnemyTank enemyTank = enemyTanks.get(j);
					hitTank(shot, enemyTank);
				}
			}
		}
	}

	//什么时候判断我方的子弹是否击中敌人坦克？run方法
	public static void hitTank(Shot s, Tank enemyTank) {
		//判断s 击中坦克
		switch (enemyTank.getDirection()) {
			case 0://坦克向上
			case 2://坦克向下
				if (s.x > enemyTank.getX() && s.x < enemyTank.getX() + 40
						&& s.y > enemyTank.getY() && s.y < enemyTank.getY() + 60) {
					s.isLive = false;
					enemyTank.isLive = false;
					//创建bomb对象，加入到bombs集合
					Bomb bomb = new Bomb(enemyTank.getX(), enemyTank.getY());
					bombs.add(bomb);
					if (enemyTank instanceof EnemyTank) {
						Recorder.addAllEnemyTanknum();
					}
				}
				break;
			case 1://坦克向右
			case 3://坦克向左
				if (s.x > enemyTank.getX() && s.x < enemyTank.getX() + 60
						&& s.y > enemyTank.getY() && s.y < enemyTank.getY() + 40) {
					s.isLive = false;
					enemyTank.isLive = false;
					//创建bomb对象，加入到bombs集合
					Bomb bomb = new Bomb(enemyTank.getX(), enemyTank.getY());
					bombs.add(bomb);
					if (enemyTank instanceof EnemyTank) {
						Recorder.addAllEnemyTanknum();
					}
				}
				break;
		}
	}
	public void showInfo(Graphics g){
		//画出玩家总成绩
		g.setColor(Color.BLACK);
		Font font = new Font("宋体", Font.BOLD, 25);
		g.setFont(font);
		g.drawString("您累计击毁敌方坦克",1020,30);
		drawTank(1020,60,g,0,1);//画出一个敌方坦克
		g.setColor(Color.BLACK);
		g.drawString(String.valueOf(Recorder.getAllEnemyTanknum()),1080,100);
	}
	@Override
	public void paint(Graphics g) {
		super.paint(g);
		showInfo(g);
		g.fillRect(0, 0, 1000, 750);//填充矩形，默认黑色
		if (myTank.isLive) {
			//画出我方坦克
			drawTank(myTank.getX(), myTank.getY(), g, myTank.getDirection(), 0);

			//画出我方坦克射击的子弹
			for (int i = 0; i < myTank.shots.size(); i++) {
				Shot shot = myTank.shots.get(i);
				if (shot != null && shot.isLive) {
					g.fill3DRect(shot.x, shot.y, 3, 3, false);
				} else {
					//如果该shot对象已经无效，就将其从集合中删除
					myTank.shots.remove(shot);
				}
			}
		}


		//如果bombs集合中有对象，就画出炸弹
		for (int i = 0; i < bombs.size(); i++) {
			//取出炸弹
			Bomb bomb = bombs.get(i);
			//根据当前这个对象的life值去画出对应图片
			if (bomb.life > 6) {
				g.drawImage(image1, bomb.x, bomb.y, 60, 60, this);
			} else if (bomb.life > 3) {
				g.drawImage(image2, bomb.x, bomb.y, 60, 60, this);
			} else {
				g.drawImage(image3, bomb.x, bomb.y, 60, 60, this);
			}
			//让炸弹的生命值减少
			bomb.lifeDown();
			if (bomb.life == 0) {//从集合中删除
				bombs.remove(bomb);

			}
		}
		//画出敌方坦克
		for (int i = 0; i < enemyTanks.size(); i++) {
			//取出坦克
			EnemyTank enemyTank = enemyTanks.get(i);
			//判断当前坦克是否存活
			if (enemyTank.isLive) {
				drawTank(enemyTank.getX(), enemyTank.getY(), g, enemyTank.getDirection(), 1);
				//画出所有子弹
				for (int j = 0; j < enemyTank.shots.size(); j++) {
					Shot shot = enemyTank.shots.get(j);
					if (shot != null && shot.isLive) {//子弹存在
						g.fill3DRect(shot.x, shot.y, 3, 3, false);
					} else {
						//从vector中移除
						enemyTank.shots.remove(shot);
					}
				}
			} else {
				//敌方坦克不存活，移除出集合
				enemyTanks.remove(enemyTank);
			}
		}
	}

	/**
	 * @param x         坦克的左上角x坐标
	 * @param y         坦克的左上角y坐标
	 * @param g         画笔
	 * @param direction 坦克方向（上下左右）
	 * @param type      坦克类型
	 */
	public void drawTank(int x, int y, Graphics g, int direction, int type) {
		switch (type) {
			case 0: {
				//我方坦克
				g.setColor(Color.cyan);
				break;
			}
			case 1: {
				g.setColor(Color.yellow);
				break;
			}
		}
		//根据坦克方向，来绘制坦克，direct：0表示向上，1表示向右，2表示向下，3表示向左
		switch (direction) {
			case 0:
				//向上
				g.fill3DRect(x, y, 10, 60, false);//画出坦克左边轮子
				g.fill3DRect(x + 30, y, 10, 60, false);//画出坦克右边轮子
				g.fill3DRect(x + 10, y + 10, 20, 40, false);//画出坦克盖子
				g.fillOval(x + 10, y + 20, 20, 20);//画出坦克圆盖
				g.drawLine(x + 20, y, x + 20, y + 30);//画出炮筒
				break;
			case 1:
				//向右
				g.fill3DRect(x, y, 60, 10, false);//画出坦克上边轮子
				g.fill3DRect(x, y + 30, 60, 10, false);//画出坦克下边轮子
				g.fill3DRect(x + 10, y + 10, 40, 20, false);//画出坦克盖子
				g.fillOval(x + 20, y + 10, 20, 20);//画出坦克圆盖
				g.drawLine(x + 30, y + 20, x + 60, y + 20);//画出炮筒
				break;
			case 2:
				//向下
				g.fill3DRect(x, y, 10, 60, false);//画出坦克左边轮子
				g.fill3DRect(x + 30, y, 10, 60, false);//画出坦克右边轮子
				g.fill3DRect(x + 10, y + 10, 20, 40, false);//画出坦克盖子
				g.fillOval(x + 10, y + 20, 20, 20);//画出坦克圆盖
				g.drawLine(x + 20, y + 60, x + 20, y + 30);//画出炮筒
				break;
			case 3:
				//向左
				g.fill3DRect(x, y, 60, 10, false);//画出坦克上边轮子
				g.fill3DRect(x, y + 30, 60, 10, false);//画出坦克下边轮子
				g.fill3DRect(x + 10, y + 10, 40, 20, false);//画出坦克盖子
				g.fillOval(x + 20, y + 10, 20, 20);//画出坦克圆盖
				g.drawLine(x + 30, y + 20, x, y + 20);//画出炮筒
				break;
			default:
				System.out.println("暂时没有处理");
		}
	}

	@Override
	public void keyTyped(KeyEvent e) {

	}

	@Override
	public void keyPressed(KeyEvent e) {
		if (e.getKeyCode() == KeyEvent.VK_W) {
			//按下w键
			myTank.setDirection(0);
			if (myTank.getY() > 0) {
				myTank.moveUp();
			}
		} else if (e.getKeyCode() == KeyEvent.VK_D) {
			//按下d键
			myTank.setDirection(1);
			if (myTank.getX() + 60 < 1000) {
				myTank.moveRight();
			}
		} else if (e.getKeyCode() == KeyEvent.VK_S) {
			//按下s键
			myTank.setDirection(2);
			if (myTank.getY() + 60 < 750) {
				myTank.moveDown();
			}
		} else if (e.getKeyCode() == KeyEvent.VK_A) {
			//按下a键
			myTank.setDirection(3);
			if (myTank.getX() > 0) {
				myTank.moveLeft();
			}
		}
		//如果用户按下J键，就发射
		if (e.getKeyCode() == KeyEvent.VK_J) {
			myTank.shotEnemyTank();
		}
		this.repaint();
	}

	@Override
	public void keyReleased(KeyEvent e) {

	}

	@Override
	public void run() {//每隔100ms重绘区域，刷新绘图区域，子弹就移动
		while (true) {
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				throw new RuntimeException(e);
			}
			hitEnemyTank(myTank.shots, enemyTanks);
			hitMyTank();
			this.repaint();
		}

	}
}
